return hid_match_device(hdev, hdrv) != NULL;
}
+static void clear_status_flag(unsigned int flag, unsigned int *status)
+{
+ unsigned int expect, old;
+
+ expect = READ_ONCE(*status);
+ for (;;) {
+ old = cmpxchg(status, expect, expect & ~flag);
+ if (old == expect)
+ break;
+ expect = old;
+ }
+}
+
+static bool test_and_set_status_flag(unsigned int flag, unsigned int *status)
+{
+ unsigned int expect, old;
+
+ expect = READ_ONCE(*status);
+ for (;;) {
+ old = cmpxchg(status, expect, expect | flag);
+ if (old == expect)
+ break;
+ expect = old;
+ }
+
+ return old & flag;
+}
+
static int hid_device_probe(struct device *dev)
{
struct hid_driver *hdrv = to_hid_driver(dev->driver);
}
hdev->io_started = false;
- clear_bit(ffs(HID_STAT_REPROBED), &hdev->status);
+ clear_status_flag(HID_STAT_REPROBED, &hdev->status);
if (!hdev->driver) {
id = hid_match_device(hdev, hdrv);
if (hdev->driver == hdrv &&
!hdrv->match(hdev, hid_ignore_special_drivers) &&
- !test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status))
+ !test_and_set_status_flag(HID_STAT_REPROBED, &hdev->status))
return device_reprobe(dev);
return 0;
bool battery_avoid_query;
#endif
- unsigned long status; /* see STAT flags above */
+ unsigned int status; /* see STAT flags above */
unsigned claimed; /* Claimed by hidinput, hiddev? */
unsigned quirks; /* Various quirks the device can pull on us */
bool io_started; /* If IO has started */